home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* file 3
- /* SUMMARY
- /* manipulate ordinary files
- /* PROJECT
- /* pc-mail
- /* PACKAGE
- /* mail
- /* SYNOPSIS
- /* int file()
- /*
- /* int junk_file()
- /* DESCRIPTION
- /* file() is called when the user selected the "file" option
- /* in the main menu. The pager displays a directory listing on the
- /* screen. The user may then walk through the file display and
- /* select a file or directory.
- /*
- /* In case a regular file is selected the user may specify
- /* an action (send file as mail, delete file, display
- /* file, print file, copy file to workfile for subsequent
- /* editing etc.).
- /*
- /* junk_file() should be invoked when the file display is no longer
- /* valid.
- /* FILES
- /* By selecting directory files the user can walk through the whole
- /* file system.
- /* SEE ALSO
- /* kbdinp(3), pager(3)
- /* BUGS
- /* MS-DOS has no "." or ".." entries in the root directory, and
- /* subdirectories of an MS-DOS root directory have no ".." entry.
- /*
- /* Changing the current directory may cause problems if
- /* environment variables are defined in terms of relative path names.
- /*
- /* There is no provision to change the "default drive" on systems
- /* that use such abominations.
- /* AUTHOR(S)
- /* W.Z. Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Sun Apr 5 17:18:06 GMT+1:00 1987
- /* LAST MODIFICATION
- /* 90/01/22 13:01:37
- /* VERSION/RELEASE
- /* 2.1
- /*--*/
-
- #include <stdio.h>
- #include <time.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <ctype.h>
-
- #include "defs.h"
- #include "screen.h"
- #include "pager.h"
- #include "mail.h"
- #include "ndir.h"
- #include "path.h"
- #include "status.h"
- #include "window.h"
-
- extern struct tm *localtime(); /* std C library */
-
- hidden File *bldlist(); /* forward declaration */
- hidden int show_list();
- hidden int pick_file();
- hidden int delfile();
- hidden int show_file();
- hidden int rmfile();
-
- hidden File *dfile = 0; /* file listing */
- hidden File *dirfile = 0; /* directory listing */
- hidden char file_prompt[BUFSIZ]; /* prompt with directory name */
- hidden char file_dir[BUFSIZ]; /* prompt with directory name */
- hidden char prompt_fmt[] = "To display a file, select it with \
- the cursor keys, then press ENTER\n(showing directory: \"%s\")";
-
- /* file - called from keyboard interpreter, call keyboard driver */
-
- public int file()
- {
- char *getcwd();
- char thisdir[BUFSIZ];
-
- static Screen screen[] = {
- 'C', "Close",0, prevscreen,
- 'P', "Print",print, "Print file listing",
- 'S', "Save", save, "Save file listing to ordinary file",
- PGUP, PgUp, pu_pager,pageup,
- PGDN, PgDn, pd_pager,pagedn,
- UP, "Up", up_pager,csrup,
- DOWN, "Down", dn_pager,csrdn,
- ENTER, "Enter",pick_file,"Display file at cursor",
- 0, 0, show_list,
- file_prompt,
- };
-
- (void) getcwd(thisdir, sizeof(thisdir)); /* save current directory */
- sprintf(file_prompt, prompt_fmt, thisdir); /* put cwd in prompt */
- kbdinp(screen); /* set up dialogue */
- close_pager(dirfile); /* deallocate pager file */
- dirfile = 0; /* say it's gone */
- (void) chdir(thisdir); /* restore current directory */
- return (S_REDRAW); /* force screen update */
- }
-
- /* show_list - create or refresh file listing */
-
- hidden int show_list()
- {
- if (dirfile == 0) { /* no pager file? */
- dirfile = bldlist(); /* create one */
- } else {
- set_pager(dirfile); /* select existing pager file */
- }
- ds_pager(); /* display the thing */
- return (0); /* say screen is up-to-date */
- }
-
- /* bldlist - build file listing display */
-
- hidden File *bldlist()
- {
- register File *pp;
- register DIR *dp;
- register struct direct *de;
- struct stat s;
-
- patience();
-
- if ((dp = opendir(THISDIR)) == 0) {
- fatal("insufficient memory for operation");
- /* NOTREACHED */
- } else {
- pp = open_pager(); /* allocate pager file */
-
- while (de = readdir(dp)) { /* read next file name */
- if (stat(de->d_name, &s) == 0) { /* get file info */
- if ((s.st_mode & S_IFMT) == S_IFDIR)
- app_pager(pp, strcons("%-20s %9s %s", de->d_name,
- "<dir>", tstamp(&s.st_mtime)));
- else
- app_pager(pp, strcons("%-20s %9ld %s", de->d_name,
- s.st_size, tstamp(&s.st_mtime)));
- }
- }
- sort_pager(pp, FORW_SORT); /* sort by file name */
-
- (void) getcwd(file_dir, sizeof(file_dir));
- sprintf(file_prompt, prompt_fmt, file_dir); /* put cwd in prompt */
-
- closedir(dp); /* directory search done */
- return (pp); /* current pager file */
- }
- }
- /* pick_file - display selected file or change directory */
-
- hidden int pick_file()
- {
- static char botline[80];
- static Screen screen[] = {
- 'C', "Close",0, "Return to file listing",
- 'D', "Delete",delfile, "Delete this file",
- 'M', "Mail", mailfile, "Mail a copy of this file",
- 'P', "Print",print, "Print this file",
- 'S', "Save", save, "Save a copy to an ordinary file",
- 'W', "Work", makework, "Save a copy to a work file",
- '|', "|", filter, "Filter file through command",
- PGUP, PgUp, pu_pager, pageup,
- PGDN, PgDn, pd_pager, pagedn,
- UP, "Up", up_pager, csrup,
- DOWN, "Down", dn_pager, csrdn,
- 0, 0, show_file,
- botline,
- };
- struct stat s;
-
- if (!sscanf(gets_pager(), "%s", message)) { /* cannot read name */
- beep(); /* "notify" user */
- return (0); /* nothing happened */
- } else if (access(message, 04)
- || stat(message, &s)) { /* cannot read file */
- beep(); /* "notify" user */
- return (0); /* nothing happened */
- } else if ((s.st_mode & S_IFMT) == S_IFDIR) { /* directory file */
- chdir(message); /* change directory */
- close_pager(dirfile); /* purge display */
- dirfile = bldlist(); /* new file display */
- return (S_REDRAW); /* update display */
- } else { /* ordinary file */
- sprintf(botline, "(Reading file \"%s\")", message);
- kbdinp(screen); /* look at screen */
- close_pager(dfile); /* and forget it */
- dfile = 0; /* say it's gone */
- return (S_REDRAW); /* force redrawing */
- }
- }
-
- /* show_file - create or refresh display of selected file */
-
- hidden int show_file()
- {
- if (dfile) {
- set_pager(dfile); /* select dispay */
- } else {
- if (rd_pager(dfile = open_pager(),
- message)) /* try to read file */
- mesg_pager(dfile, m_msgread); /* read error */
- }
- ds_pager(); /* rewrite screen */
- return (0); /* screen up-to-date */
- }
-
- /* delfile - ask confirmation before removing a file */
-
- hidden int delfile()
- {
- static Screen screen[] = {
- ESCCR, 0, rmfile, int_error,
- 0, 0, 0,
- "Press ESC to cancel. Confirm with ENTER",
- };
-
- return (kbdinp(screen) | S_REDRAW); /* "are you sure?" */
- }
-
- /* rmfile - actually remove file */
-
- hidden int rmfile()
- {
- if (unlink(message)) { /* try to remove file */
- errdisp(E_UNLINK); /* notify the user */
- return (S_BREAK | S_REDRAW); /* redisplay, stop caller */
- } else {
- junk_file(); /* say file display outdated */
- return (S_BREAK); /* terminate caller */
- }
- }
-
- /* junk_file - directory listing is no longer up to date */
-
- public int junk_file()
- {
- if (dirfile) {
- close_pager(dirfile); /* close pager file */
- dirfile = 0; /* say it is gone */
- }
- return (0); /* in case we need that */
- }
-